package com.card.game;

import java.util.Collections;
import java.util.List;
import java.util.Vector;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;

public class AqUtils {
	public static ImmutableList<Card> AllCards = ImmutableList.copyOf(getAllCard(true));
	public static ImmutableList<Card> NoFengAllCards = ImmutableList.copyOf(getAllCard(false));
	public static ImmutableList<Card> HuCards = ImmutableList.copyOf(getAllCard());

	private static List<Card> getAllCard(boolean haveFeng) {
		List<Card> cc = Lists.newArrayList();
		for (int i = CardType.WAN; i <= CardType.BING; i++) {
			for (int j = 1; j < 10; j++) {
				Card c = new Card(i, j);
				cc.add(c);
			}
		}
		if(haveFeng) {
			for (int i = CardType.DONG; i <= CardType.BAI; i++) {
				Card c = new Card(i, 0);
				cc.add(c);
			}
		}
		return cc;
	}

	private static Vector<Card> getAllVCard(boolean haveFeng) {
		Vector<Card> cc = new Vector<>();
		for (int i = CardType.WAN; i <= CardType.BING; i++) {
			for (int j = 1; j < 10; j++) {
				Card c = new Card(i, j);
				cc.add(c);
			}
		}
		if (haveFeng) {
			for (int i = CardType.DONG; i <= CardType.BAI; i++) {
				Card c = new Card(i, 0);
				cc.add(c);
			}
		}
		return cc;
	}

	private static List<Card> getAllCard() {
		List<Card> cc = Lists.newArrayList();
		for (int i = CardType.WAN; i <= CardType.BING; i++) {
			for (int j = 1; j < 10; j++) {
				cc.add(new Card(i, j));
			}
		}
		for (int i = CardType.NAN; i <= CardType.BEI; i++) {
			cc.add(new Card(i, 0));
		}
		return cc;
	}

	public static boolean isHuPai(List<Integer> sours2, int huCard) {
		// System.out.println("AqUtils--isHuPai");
		if (MMHandUtils.isCanHu(sours2, huCard)) {
			List<Integer> clones = Lists.newArrayList(sours2);
			clones.add(huCard);
			return MMHandUtils.isHuPai(clones);
		}
		return false;
	}

	public static boolean isZimo(Vector<Card> sours2, Card huCard) {
		// System.out.println("isZimo--isHuPai");
		return MMHandUtils.isHuPai(sours2);
	}

	// ��ȡ����ֵ
	public static List<Card> getTingCards(Vector<Card> cards, boolean haveFeng, Card hunzi) {
		List<Card> tings = Lists.newArrayList();

		ImmutableList<Card> allPais = ImmutableList.copyOf(getAllCard(haveFeng));
		// ����л���
		if (hunzi.getType() > 0) {
			// ��������л���
			Vector<Card> noHunCards = new Vector<>();
			int huncount = 0;
			for (Card card : cards) {
				if (card.equals(hunzi)) {
					huncount++;
					continue;
				}
				noHunCards.add(card);
			}
			tings = getTingCardsByHun(noHunCards, huncount, haveFeng);
			// System.out.println("��ȡ�˴���������");
			if (tings.size() > 0 && !tings.contains(hunzi)) {
				tings.add(hunzi);
			}
		} else {
			tings = getTingCards(cards, haveFeng);
		}

		return tings;
	}

	private static List<Card> getTingCardsByHun(Vector<Card> noHunCards, int huncount, boolean haveFeng) {
		// ���ݻ��ӵĸ�����ȡ����
		List<Card> tings = Lists.newArrayList();
		ImmutableList<Card> allICards = ImmutableList.copyOf(getAllCard(haveFeng));
		Vector<Card> allVCards = getAllVCard(haveFeng);
		if (huncount < 1) {
			List<Integer> sour = MMHandUtils.transInteger(noHunCards);
			for (Card c : allICards) {
				if (isHuPai(sour, c.getMm())) {
					tings.add(c);
				}
			}
		} else if (huncount == 1) {
			for (Card c : allICards) {
				for (Card card1 : allVCards) {
					Vector<Card> clone = (Vector<Card>) noHunCards.clone();
					clone.add(card1);
					List<Integer> sour = MMHandUtils.transInteger(clone);
					if (isHuPai(sour, c.getMm())) {
						tings.add(c);
						break;
					}
				}
			}
		} else if (huncount == 2) {
			for (Card c : allICards) {
				first:
				for (Card card1 : allVCards) {
					Vector<Card> clone1 = (Vector<Card>) noHunCards.clone();
					clone1.add(card1);
					for (Card card2 : allVCards) {
						Vector<Card> clone2 = (Vector<Card>) clone1.clone();
						clone2.add(card2);
						List<Integer> sour = MMHandUtils.transInteger(clone2);
						if (isHuPai(sour, c.getMm())) {
							tings.add(c);
							break first;
						}
					}
				}
			}
		} else if (huncount == 3) {
			tings = getAllCard(haveFeng);
//			for (Card c : allICards) {
//				first:
//				for (Card card1 : allVCards) {
//					Vector<Card> clone1 = (Vector<Card>) noHunCards.clone();
//					clone1.add(card1);
//					for (Card card2 : allVCards) {
//						Vector<Card> clone2 = (Vector<Card>) clone1.clone();
//						clone2.add(card2);
//						List<Integer> sour = MMHandUtils.transInteger(clone2);
//						if (isHuPai(sour, c.getMm())) {
//							tings.add(c);
//							break first;
//						}
//					}
//				}
//			}
		} else {
			tings = getAllCard(haveFeng);
		}
		return tings;
	}

	public static List<Card> getTingCards(Vector<Card> cards, boolean haveFeng) {

		List<Card> tings = Lists.newArrayList();
		// if(haveHua(cards)) {
		// return que13Lan(cards);
		// }
		List<Integer> sour = MMHandUtils.transInteger(cards);
		for (Card c : ImmutableList.copyOf(getAllCard(haveFeng))) {
			if (isHuPai(sour, c.getMm())) {
				tings.add(c);
			}
		}
		return tings;
	}
	
	public static boolean is7xing(Vector<Card> cards) {
		for (int i = CardType.DONG; i <= CardType.BAI; i++) {
			Card c = new Card(i, 0);
			if(!cards.contains(c)) {
				return false;
			}
		}
		return true;
	}
	
	private static List<Card> que13Lan(Vector<Card> cards) {
		List<Card> cc = Lists.newArrayList();
		for (Card card : AllCards) {
			if(is13Lan(cards,card)) {
				cc.add(card);
			}
		}
		return cc;
	}
	
	public static boolean haveHua(Vector<Card> cards) {
		for (Card card : cards) {
			if(card.isHuaCard()) {
				return true;
			}
		}
		return false;
	}
	
	// 清一色
	public static boolean isQingYiSe(Player player, Vector<Card> sours, Card huCard) {
		// TODO Auto-generated method stub
		Vector<Card> clones = (Vector<Card>) sours.clone();
		Collections.sort(clones);
		for (int i = CardType.WAN; i <= CardType.BING; i++) {
			Vector<Card> cc = getCardByType(clones, i);
			if (cc.size() != 14 && cc.size() != 0) {
				return false;
			}
		}
		return true;
	}

	// 一条龙
	public static boolean isYiTiaoLong(Player player, Vector<Card> sours, Card huCard) {
		// TODO Auto-generated method stub
		if (sours.size() == 14 || sours.size() == 11) {
			Vector<Card> clones = (Vector<Card>) sours.clone();
			Collections.sort(clones);
			for (int i = CardType.WAN; i <= CardType.BING; i++) {
				Vector<Card> cc = getCardByType(clones, i);
				if (cc.size() == 9) {
					return CardUtils.findSameCardBySize(cc, 2).size() == 0;
				} else if (cc.size() == 11) {
					return CardUtils.findSameCardBySize(cc, 4).size() == 0
							&& CardUtils.findSameCardBySize(cc, 3).size() == 1
							&& CardUtils.findSameCardBySize(cc, 2).size() == 0;
				} else if (cc.size() == 14 || cc.size() == 12) {
					// System.out.println(CardUtils.findSameCardBySize(cc, 2).size());
					Vector<Card> ll = new Vector<Card>();
					for (int j = 0; j < cc.size() - 1; j++) {
						if (cc.get(j).getIndex() == cc.get(j + 1).getIndex()) {
							ll.add(cc.get(j + 1));
						}
					}
					return longHu(ll);
				}
			}
		}
		return false;
	}

	private static boolean longHu(Vector<Card> ll) {
		Collections.sort(ll);
		if (ll.size() == 3) {
			if (ll.get(0).getIndex() == ll.get(1).getIndex()) {
				return ll.get(1).getIndex() == ll.get(2).getIndex();
			} else {
				return ll.get(0).getIndex() + 2 == ll.get(1).getIndex() + 1
						&& ll.get(1).getIndex() + 1 == ll.get(2).getIndex();
			}
		} else if (ll.size() == 5) {
			if (CardUtils.findSameCardBySize(ll, 2).size() == 1) {
				if (ll.get(0).getIndex() == ll.get(1).getIndex()) {
					return ll.get(1).getIndex() == ll.get(2).getIndex();
				} else {
					return ll.get(0).getIndex() + 2 == ll.get(1).getIndex() + 1
							&& ll.get(1).getIndex() + 1 == ll.get(2).getIndex();
				}
			}
		} else {
			return false;
		}
		return false;
	}
	
	//对对胡
	public static boolean isDuiDuiHu(Player player,Vector<Card> sours,Card huCard) {
//		if(player == null || player.getChiList().isEmpty()) {
		if(player == null) {
			Vector<Card> clones = (Vector<Card>)sours.clone();
			clones.add(huCard);
			Collections.sort(clones);
			CardUtils.findSameCardBySize(clones, 3);
			if(clones.size() == 2) {
				CardUtils.findSameCardBySize(clones, 2);
				return clones.isEmpty();
			}
		}
		return false;
	}
	
	public static int getMenQing(Vector<Card> cards) {
		int num = 0;
		for (int i = CardType.WAN; i <= CardType.BING; i++) {
			if(noTypeCard(cards, i)) {
				num ++;
			}
		}
		return num;
	}
	
	private static boolean noTypeCard(Vector<Card> cards,int type) {
		for (Card card : cards) {
			if(card.getType() == type) {
				return false;
			}
		}
		return true;
	}
	
	public static boolean isKaHu(Vector<Card> sours,Card huCard) {
		if(huCard.getIndex()>1 && huCard.getIndex()<9) {
			Vector<Card> clones = (Vector<Card>)sours.clone();
			if(clones.remove(new Card(huCard.getType(), huCard.getIndex()-1))
					&&clones.remove(new Card(huCard.getType(), huCard.getIndex()+1))) {
				return HandUtils.isHuPai(clones);
			}
		}
		return false;
	}
	
	public static boolean isDuiDaoHu(Vector<Card> sours,Card huCard) {
		if(sours.size() >= 4) {
			Vector<Card> clones = (Vector<Card>)sours.clone();
			Collections.sort(clones);
			if(clones.remove(huCard) && clones.remove(huCard)) {
				return HandUtils.isHuPai(clones);
			}
		}
		return false;
	}
	
	public static boolean is13Lan(Vector<Card> cards,Card card) {
		Vector<Card> clones = (Vector<Card>)cards.clone();
		clones.add(card);
		return is13Lan(clones);
	}
	
	public static boolean is13Lan(Vector<Card> sours) {
		if(sours.size() == 14) {
			Vector<Card> clones = (Vector<Card>)sours.clone();
			Collections.sort(clones);
			if(CardUtils.findSameCardBySize(clones, 2).size() == 0) {
				for (int i = CardType.WAN; i <= CardType.BING; i++) {
					Vector<Card> cc = getCardByType(clones, i);
					if(!isLanVector(cc)) {
						return false;
					}
				}
				return true;
			}
		}
		return false;
	}
	public static Vector<Card> getCardByType(Vector<Card> sours,int type) {
		Vector<Card> clones = new Vector<>();
		for (Card card : sours) {
			if(card.getType() == type) 
			clones.add(card); 
		}
		return clones;
	}
	private static boolean isLanVector(Vector<Card> sours) {
		if(sours.size()<2) {
			return true;
		}
		for (int i = 1; i < sours.size(); i++) {
			if(sours.get(i).getIndex() - sours.get(i-1).getIndex()<3) {
				return false;
			}
		}
		return true;
	}
	public static boolean isSanFeng(Card card) {
		return card.getType() == CardType.NAN
				|| card.getType() == CardType.XI || card.getType() == CardType.BEI;
	}
	
	
	public static boolean isBianHu(Vector<Card> sours,Card huCard) {
		if(huCard.getIndex() ==3) {
			Vector<Card> clones = (Vector<Card>)sours.clone();
			if(clones.remove(new Card(huCard.getType(), 1)) && clones.remove(new Card(huCard.getType(), 2))) {
				return HandUtils.isHuPai(clones);
			}
		}
		if(huCard.getIndex() ==7) {
			Vector<Card> clones = (Vector<Card>)sours.clone();
			if(clones.remove(new Card(huCard.getType(), 8)) && clones.remove(new Card(huCard.getType(), 9))) {
				return HandUtils.isHuPai(clones);
			}
		}
		return false;
	}
	
	public static void main(String[] args) {
		String cardsStr =  "1-4;1-5;3-1;3-1;3-3;3-3;3-3;";
		Vector<Card> sours = QzUtils.testCard(cardsStr);
//		Card huCard = new Card(1, 3);
		Collections.sort(sours);
		// System.err.println(isBianHu(sours, huCard));
		System.err.println(getTingCards(sours, true));
		// System.err.println(isDuiDaoHu(sours, huCard));
	}
}
